#include "TListaMensajes.h"


int LM_Crear(TListaMensajes* lista) {
	lista->tam_dato = sizeof(TElemListaMensajes);
	lista->lista_simple = (TListaSimple*) malloc(sizeof(TListaSimple));
	#ifdef __DEBUG__
	printf("LM_Crear: Entra.\n");
	#endif
	if (!(lista->lista_simple)) {
		return TLM_ERR_MEMORIA;
	}

	LS_Crear(lista->lista_simple, lista->tam_dato);
	return TLM_OK;
}

int LM_Destruir(TListaMensajes* lista) {
	/* destruir_nodos(lista->lista_simple); HAY QUE DESTRUIR LOS NODOS IGUALMENTE USANDO PRIMITIVAS */
	TElemListaMensajes* nodo = malloc(sizeof(TElemListaMensajes));

	        LS_MoverCorriente(lista->lista_simple, LS_PRIMERO);
	        while (!LS_Vacia(*(lista->lista_simple))) {
	                LS_ElemCorriente(*(lista->lista_simple), nodo);
	                TNLM_Destruir(nodo);
	                LS_BorrarCorriente(lista->lista_simple);
	        }

	        LS_Vaciar(lista->lista_simple);
	        free(nodo);
	lista->tam_dato = -1;
	free(lista->lista_simple);
	return TLM_OK;
}

int LM_InsertarMensaje(TListaMensajes* lista, TMensaje* mensaje) {
	int tamanio;
	TPuerto puerto_mensaje = Mensaje_ObtenerPuerto(mensaje);
	TTipoMensaje tipo = Mensaje_ObtenerPrioridad(mensaje);
	TElemListaMensajes* nodo;
	nodo = (TElemListaMensajes*) malloc(sizeof(TElemListaMensajes));
	Mensaje_ObtenerTamanioMensaje(mensaje, &tamanio);
	#ifdef __DEBUG__
	printf("LM_InsertarMensaje:\n tamanio = %d\n mensaje = %s\n puerto_mensaje = %d\n", tamanio, mensaje, puerto_mensaje);
	#endif


	if (LS_Vacia(*(lista->lista_simple))) {
		TNLM_Crear(nodo, puerto_mensaje, sizeof(TMensaje));
		if (tipo == PRIORITARIO){
			TNLM_InsertarMensajePrioritario(nodo,mensaje);
    }
    else if (tipo==NO_PRIORITARIO) {
      TNLM_InsertarMensajeNoPrioritario(nodo,mensaje);
  	}
		LS_Insertar(lista->lista_simple, LS_PRIMERO, nodo);
		#ifdef __DEBUG__
		printf("LM_InsertarMensaje:\n Inserto en primero\n");
		#endif
		free(mensaje);
	}
	else {
		      int encontrado = 0;
		      LS_MoverCorriente(lista->lista_simple, LS_PRIMERO);

		      while (!encontrado) {
		              int puerto_nodo;
		              nodo = (TElemListaMensajes*)malloc(sizeof(TElemListaMensajes));
		              LS_ElemCorriente(*(lista->lista_simple), nodo);

		              puerto_nodo = TNLM_ObtenerPuerto(nodo);

		              if (puerto_mensaje == puerto_nodo) {
		                      /*insertar_en_nodo(lista->lista_simple, nodo, mensaje);*/

		                      if (tipo == PRIORITARIO){
		                              TNLM_InsertarMensajePrioritario(nodo,mensaje);
		                      }else{
		                              if (tipo==NO_PRIORITARIO){
		                              TNLM_InsertarMensajeNoPrioritario(nodo,mensaje);
		                              }
		                      }
		                      encontrado = 1;
		                      LS_ModifCorriente(lista->lista_simple, nodo);

		              }
		              else if (puerto_mensaje < puerto_nodo) {
		                      /*insertar_nuevo(lista->liinsertar_en_nodosta_simple, mensaje, LS_ANTERIOR);*/
		                    /*  TElemListaMensajes* elemento;
		                      elemento = (TElemListaMensajes*) malloc(sizeof(TElemListaMensajes));
		                      TNLM_Crear(elemento, Mensaje_ObtenerPuerto(mensaje), sizeof(TMensaje));*/
		                      if (tipo == PRIORITARIO){
		                                  TNLM_InsertarMensajePrioritario(nodo,mensaje);
		                                   }else{
		                                   if (tipo==NO_PRIORITARIO){
		                                   TNLM_InsertarMensajeNoPrioritario(nodo,mensaje);
		                                   }
		                      }

		                      LS_Insertar (lista->lista_simple, LS_ANTERIOR, nodo);
		                      encontrado = 1;
		              }
		              else {
		                      if (!(LS_MoverCorriente(lista->lista_simple, LS_SIGUIENTE))) {
		                          encontrado=1;
		                          LS_Insertar (lista->lista_simple, LS_SIGUIENTE, nodo);

		                      }
		              }

		              free(nodo);
		      }
	}
    return TLM_OK;
}


int LM_ObtenerMensaje(TListaMensajes* lista, TPuerto puerto, TTipoMensaje es_prioritario, TMensaje* mensaje_out) {
	TElemListaMensajes* elem;
	int codigo_error;

	elem = (TElemListaMensajes*) malloc(sizeof(TElemListaMensajes));

	if (!elem) {
		return TLM_ERR_MEMORIA;
	}

	if (LS_Vacia(*(lista->lista_simple))) {
		#ifdef __DEBUG__
		printf("LM_ObtenerMensaje:\n Lista Vacia\n");
		#endif
		return TLM_ERR_SINMENSAJES;
	}

	LS_MoverCorriente(lista->lista_simple, LS_PRIMERO);
	LS_ElemCorriente(*(lista->lista_simple), elem);
	#ifdef __DEBUG__
	printf("puerto del elemento = %d", TNLM_ObtenerPuerto(elem));
	#endif
	while (TNLM_ObtenerPuerto(elem) < puerto) {
		LS_MoverCorriente(lista->lista_simple, LS_SIGUIENTE);
		LS_ElemCorriente(*(lista->lista_simple), elem);
	}

	if (TNLM_ObtenerPuerto(elem) > puerto) {
		#ifdef __DEBUG__
		printf("LM_ObtenerMensaje:\n No existe puerto\n");
		#endif
		free(elem);
		return TLM_ERR_SINMENSAJES;
	}
	else {
		#ifdef __DEBUG__
		printf("LM_ObtenerMensaje:\n Puerto encontrado\n");
		#endif
		if (es_prioritario) {
			codigo_error = TNLM_ObtenerMensajePrioritario(elem, mensaje_out);
			if (TNLM_ObtenerPuerto(elem) == -1){
			  LS_BorrarCorriente(lista->lista_simple);
			  free(elem);
			  return TLM_OK;
		  }
		  free(elem);
		  return codigo_error;
		}
		else {
			codigo_error = TNLM_ObtenerMensajeNoPrioritario(elem, mensaje_out);
			if (TNLM_ObtenerPuerto(elem) == -1) {
				LS_BorrarCorriente(lista->lista_simple);
				free(elem);
				return TLM_OK;
			}

			free(elem);
			return codigo_error;
		}
	}
}
